package com.whales.lms.rms.web.service;

import java.util.List;

import javax.inject.Inject;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.XMLOutputter;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import anyframe.common.Page;

import com.whales.lms.rms.scheduler.service.IFService;
import com.whales.lms.rms.web.model.PcVO;
import com.whales.lms.rms.web.model.SoftwareVO;
import com.whales.lms.rms.web.util.ConstantUtil;
import com.whales.shared.exception.BaseException;
import com.whales.shared.service.GenericService;
import com.whales.shared.util.FileUtil;
import com.whales.shared.util.SessionUtil;

@Service
public class SoftwareService extends GenericService<SoftwareVO, SoftwareVO> {
	private final String SAVE_FILE_PATH = "C:\\file\\sw";
	@Inject
	private PcItemService pcItemService;
	@Inject
	private PcService pcService;
	@Inject
	private IFService ifService;
	
	@Override
	public int create(SoftwareVO softwareVO) throws Exception{
		SoftwareVO checkVO = new SoftwareVO();
		checkVO.setName(softwareVO.getName());
		if(this.findByName(checkVO).size() > 0){
			throw new BaseException(super.getMessage("rms.msg.exitsDuplicatedSoftware"));
		}
		softwareVO.setId(this.getNewId());
		MultipartFile multipartFile = softwareVO.getSoftwareFile();
		if(multipartFile != null){
			String fileName = multipartFile.getOriginalFilename();
	        String saveFilePath = SAVE_FILE_PATH + "\\" + softwareVO.getId() + "\\" + fileName;
	        softwareVO.setFileName(fileName);
	        softwareVO.setSvrPath(saveFilePath);
	        // 파일 저장
	        if(!FileUtil.saveFile(multipartFile, saveFilePath)){
	            throw new BaseException(super.getMessage("rms.msg.foundErrorDuringSavingFile"));//"파일 저장시 오류가 발생하였습니다."
	        }
		}
		return commonDao.create("software.createSoftware", softwareVO);
	}
	
	@Override
	public int delete(SoftwareVO softwareVO) throws Exception{
		for (int i = 0; i < softwareVO.getIds().length; i++) {
			SoftwareVO vo = new SoftwareVO();
			vo.setId(softwareVO.getIds()[i]);
			//파일 삭제
			this.deleteSoftwareFile(vo);
			//소프트웨어 삭제
			super.delete("software.deleteSoftwareById", vo);
			//PC Item 삭제
			pcItemService.deleteByHwSwId(vo);
		}
		return super.delete(softwareVO);
	}
	
	@Override
	public SoftwareVO findInfo(SoftwareVO softwareVO) throws Exception{
		return super.findInfo("software.getSoftwareById", softwareVO);
	}
	
	public List<SoftwareVO> findByName(SoftwareVO softwareVO) throws Exception{
		return super.getList("software.findByName", softwareVO);
	}

	@Override
	public List<SoftwareVO> getList(SoftwareVO softwareVO) throws Exception{
		return super.getList("software.getSoftwareList", softwareVO);
	}
	
	@Override
	public Page getPageList(SoftwareVO vo) throws Exception {
		return super.getPageList("software.getSoftwareList", vo, vo.getStart(), vo.getLimit());
	}
	
	@Override
	public int update(SoftwareVO softwareVO) throws Exception{
		MultipartFile multipartFile = softwareVO.getSoftwareFile();
		if(multipartFile.getSize() > 0){
			//기존파일 삭제
			this.deleteSoftwareFile(softwareVO);
			
			String fileName = multipartFile.getOriginalFilename();
	        String saveFilePath = SAVE_FILE_PATH + "\\" + softwareVO.getId() + "\\" + fileName;
	        softwareVO.setFileName(fileName);
	        softwareVO.setSvrPath(saveFilePath);
	        // 파일 저장
	        if(!FileUtil.saveFile(multipartFile, saveFilePath)){
	        	throw new BaseException(super.getMessage("rms.msg.foundErrorDuringSavingFile"));//"파일 저장시 오류가 발생하였습니다."
	        }
		}
		//version이 변경되면 관련 PC에 대해 자동 업데이트를 수행한다.
		//반드시 Software 업데이트보다 먼저 수행되어야 함.
		this.softwareAutoUpdate(softwareVO);
		return super.update("software.updateSoftwareById", softwareVO);
	}
	
	private void softwareAutoUpdate(SoftwareVO newSoftwareVO) throws Exception{
		SoftwareVO oldSoftwareVO = this.findInfo(newSoftwareVO); 
		//software version이 변경되었으면 해당 software를 사용하는 PC에 대해 자동 업데이트를 실행한다. 
		if(!oldSoftwareVO.getFileVer().equals(newSoftwareVO.getFileVer())){
			//해당 Software를 사용하는 PC 조회
			for(PcVO pc : pcService.getPcBySoftwareId(newSoftwareVO.getId())){
				ifService.softwareVersionUpdate(pc.getIp());
			}
		}
	}
	
	private void deleteSoftwareFile(SoftwareVO softwareVO) throws Exception{
		//파일 삭제
		SoftwareVO deleteSoftwareFile = this.findInfo(softwareVO);
		if(deleteSoftwareFile != null){
			FileUtil.removeFile(deleteSoftwareFile.getSvrPath());
			FileUtil.deleteDirectory(SAVE_FILE_PATH + "\\" + softwareVO.getId());
		}
	}

	public String getVersionByIp(String ip) {
		Document doc = new Document();
		Element root = new Element("sever-response");
		doc.setRootElement(root);
		Element result = new Element("result");
		root.addContent(result);
		
		try {
			List<SoftwareVO> list = this.getVersionListByIp(ip);
			result.setText((list.size() > 0) ?ConstantUtil.STATE_OKE:ConstantUtil.STATE_ERR);
			for (SoftwareVO vo : list) {
				Element swlist = new Element("swlist");
				swlist.addContent(this.addSoftwareElement("name",vo.getFileName()));//.replace(".zip", ".exe")
				swlist.addContent(this.addSoftwareElement("svrpath",SessionUtil.getAttribute("SERVER_FULL_PATH")+"/software/downloadSoftware.do?id="+vo.getId()));
				swlist.addContent(this.addSoftwareElement("version",vo.getFileVer()));
				root.addContent(swlist);		
			}
		} catch (Exception e) {
			result.setText(ConstantUtil.STATE_ERR);
			e.printStackTrace();
		}
		return new XMLOutputter().outputString(doc);
	}
	
	public List<SoftwareVO> getVersionListByIp(String ip) throws Exception{
		if(ConstantUtil.AGENT.equalsIgnoreCase(ip)){
			return this.getAgentList();
		}else{
			SoftwareVO softwareVO = new SoftwareVO();
			softwareVO.setIp(ip);
			return super.getList("software.getSoftwareByIp", softwareVO);
		}
	}
	
	private List<SoftwareVO> getAgentList() throws Exception{
		SoftwareVO softwareVO = new SoftwareVO();
		softwareVO.setType(ConstantUtil.AGENT);
		return this.getList(softwareVO);
	}
	
	public Element addSoftwareElement(String elementName, String value){
		Element returnElement = new Element(elementName);
		returnElement.setText(value);
		return returnElement;
	}
}
